package powernode.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.amqp.core.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
@ConfigurationProperties(prefix = "my")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RabbitConfig {
    private String exchangeNormalName;
    private String queueNormalName;
    private String exchangeDlxName;
    private String queueDlxName;

    /**
     * 声明正常使用的直接交换机
     * @return DirectExchange类型的Bean，代表正常交换机
     */
    @Bean
    public DirectExchange normalExchange(){
        return ExchangeBuilder.directExchange(exchangeNormalName).build();
    }

    /**
     * 声明正常使用的队列，包含消息过期时间和死信交换机、死信路由键的设置
     * @return Queue类型的Bean，代表正常队列
     */
    @Bean
    public Queue normalQueue(){
        Map<String, Object> arguments = new HashMap<>();
        // 设置这两个参数
        arguments.put("x-dead-letter-exchange", exchangeDlxName); // 设置该队列的死信交换机
        arguments.put("x-dead-letter-routing-key", "error"); // 设置该队列的死信路由键K，要和死信交换机中的路由键保持一致
        return QueueBuilder.durable(queueNormalName)
                .withArguments(arguments)  // 设置队列的参数
                .build();
    }

    /**
     * 将正常队列绑定到正常交换机上
     * @param normalExchange 正常交换机
     * @param normalQueue 正常队列
     * @return Binding类型的Bean，代表正常队列和正常交换机的绑定关系
     */
    @Bean
    public Binding bindingNormal(DirectExchange normalExchange, Queue normalQueue){
        return BindingBuilder.bind(normalQueue).to(normalExchange).with("order");
    }

    /**
     * 声明死信直接交换机
     * @return DirectExchange类型的Bean，代表死信交换机
     */
    @Bean
    public DirectExchange dlxExchange(){
        return ExchangeBuilder.directExchange(exchangeDlxName).build();
    }

    /**
     * 声明死信队列
     * @return Queue类型的Bean，代表死信队列
     */
    @Bean
    public Queue dlxQueue(){
        return QueueBuilder.durable(queueDlxName).build();
    }

    /**
     * 将死信队列绑定到死信交换机上
     * @param dlxExchange 死信交换机
     * @param dlxQueue 死信队列
     * @return Binding类型的Bean，代表死信队列和死信交换机的绑定关系
     */
    @Bean
    public Binding bindingDlx(DirectExchange dlxExchange, Queue dlxQueue){
        return BindingBuilder.bind(dlxQueue).to(dlxExchange).with("error");
    }

}
